import os
import cv2 as cv
import time
import random
import numpy as np
import base64
import re
from info import Info
from selenium.webdriver import ActionChains


class Kvalidate:

    def get_move_length(self, bg_png, gap_png):
        img_page_ratio = 1.285
        bg = os.path.join(Info.temp_img_path, 'bg.jpg')
        gap = os.path.join(Info.temp_img_path, 'gap.jpg')
        # 灰度处理
        cv.imwrite(bg, cv.imread(bg_png, 0))
        cv.imwrite(gap, cv.imread(gap_png, 0))
        # 匹配图片
        cv.imwrite(gap, abs(255 - cv.cvtColor(cv.imread(gap), cv.COLOR_BGR2GRAY)))
        result = cv.matchTemplate(cv.imread(gap), cv.imread(bg), cv.TM_CCOEFF_NORMED)
        x, y = np.unravel_index(result.argmax(), result.shape)
        cv.rectangle(cv.imread(bg), (y + 20, x + 20), (y + 136 - 25, x + 136 - 25), (7, 249, 151), 2)
        move_length = y / img_page_ratio
        return move_length

    def __init__(self, driver):
        self.driver = driver

    def slider_action(self, tracks, slider):
        # 点击滑块
        ActionChains(self.driver).click_and_hold(on_element=slider).perform()
        # 正向滑动
        for track in tracks['forward_tracks']:
            yoffset_random = random.uniform(-2, 4)
            ActionChains(self.driver).move_by_offset(xoffset=track, yoffset=yoffset_random).perform()
        time.sleep(random.uniform(0.06, 0.5))
        # 反向滑动
        for back_tracks in tracks['back_tracks']:
            yoffset_random = random.uniform(-2, 2)
            ActionChains(self.driver).move_by_offset(xoffset=back_tracks, yoffset=yoffset_random).perform()
        # 抖动
        ActionChains(self.driver).move_by_offset(
            xoffset=self.get_random_float(0, -1.67),
            yoffset=self.get_random_float(-1, 1)
        ).perform()
        ActionChains(self.driver).move_by_offset(
            xoffset=self.get_random_float(0, 1.67),
            yoffset=self.get_random_float(-1, 1)
        ).perform()
        time.sleep(self.get_random_float(0.6, 1))
        ActionChains(self.driver).release().perform()
        time.sleep(0.5)

        # 滑动轨迹
    def get_tracks(self, distance):
        track = []
        mid1 = round(distance * random.uniform(0.1, 0.2))
        mid2 = round(distance * random.uniform(0.65, 0.76))
        mid3 = round(distance * random.uniform(0.84, 0.88))
        # 设置初始位置、初始速度、时间间隔
        current, v, t = 0, 0, 0.2
        distance = round(distance)

        while current < distance:
            # 四段加速度
            if current < mid1:
                a = random.randint(10, 15)
            elif current < mid2:
                a = random.randint(30, 40)
            elif current < mid3:
                a = -70
            else:
                a = random.randint(-25, -18)
            # 初速度 v0
            v0 = v
            # 当前速度 v = v0 + at
            v = v0 + a * t
            v = v if v >= 0 else 0
            move = v0 * t + 1 / 2 * a * (t ** 2)
            move = round(move if move >= 0 else 1)
            # 当前位移
            current += move
            # 加入轨迹
            track.append(move)
        print("current={}, distance={}".format(current, distance))
        # 超出范围
        back_tracks = []
        out_range = distance - current
        if out_range < -8:
            sub = int(out_range + 8)
            back_tracks = [-1, sub, -3, -1, -1, -1, -1]
        elif out_range < -2:
            sub = int(out_range + 3)
            back_tracks = [-1, -1, sub]

        print("forward_tracks={}, back_tracks={}".format(track, back_tracks))
        return {'forward_tracks': track, 'back_tracks': back_tracks}

    def get_random_float(self,min, max, digits=4):
        return round(random.uniform(min, max), digits)

    def move_slider_simulate_human(self, move_length, slider):
        fake_length = random.random(1,5)
        move_length += fake_length
        action = ActionChains(self.driver)
        time.sleep(1)
        slider = self.driver.find_element_by_class_name('JDJRV-slide-btn')
        time.sleep(1)
        action.click_and_hold(slider).perform()
        action.drag_and_drop_by_offset(slider, move_length, 0).perform()

    def move_slider(self, move_length, slider):
        action = ActionChains(self.driver)
        time.sleep(1)
        slider = self.driver.find_element_by_class_name('JDJRV-slide-btn')
        time.sleep(1)
        action.click_and_hold(slider).perform()
        action.drag_and_drop_by_offset(slider, move_length, 0).perform()

    def get_move_length2(self, bg_img, gap_img):
        bg = cv.imread(bg_img)
        gap = cv.imread(gap_img)
        # 灰度降维
        gap = cv.cvtColor(gap, cv.COLOR_BGR2GRAY)
        bg = cv.cvtColor(bg, cv.COLOR_BGR2GRAY)
        # gap = gap[gap.any(0)]
        # 相似度匹配
        result = cv.matchTemplate(bg, gap, cv.TERM_CRITERIA_MAX_ITER)
        # 获取最高匹配点坐标
        x,y = np.unravel_index(np.argmax(result), result.shape)
        w,h = gap.shape
        if Info.debug:
            cv.rectangle(bg, (y, x), (y + h, x + w), (38, 38, 38), 2)
            print(x,y)
            cv.imshow('gray', bg)
            cv.waitKey(0)
        return x+w

    def save_base64_to_png(self, base64_data):
        data = base64_data.split('base64,', 1)[1]
        img = base64.b64decode(data)
        img_path = os.path.join(Info.temp_img_path,  str(time.time())+'.png')
        with open(img_path, 'wb+') as f:
            f.write(img)
        return img_path
